#include "ProcInfoPlugin.h"

ProcInfoPlugin::ProcInfoPlugin(QObject *parent)
    : QObject(parent)
    , m_model(new ProcInfoModel(this))
    , m_procInfoWidget(nullptr)
    , m_tipLabel(nullptr)
{
}

const QString ProcInfoPlugin::pluginName() const
{
    return "CccProcInfoPlugin";
}

const QString ProcInfoPlugin::pluginDisplayName() const
{
    return QString("ProcInfo");
}

void ProcInfoPlugin::init(PluginProxyInterface *proxyInter)
{
    m_proxyInter = proxyInter;
    m_procInfoWidget = new ProcInfoWidget;
    // 如果插件没有被禁用则在初始化插件时才添加主控件到面板上
    if (!pluginIsDisable()) {
        m_proxyInter->itemAdded(this, pluginName());
    }

    m_tipLabel = new DLabel("↑0.0K/s\n↓0.0K/s");
    m_tipLabel->setContentsMargins(3, 3, 3, 3);

    // init connections
    connect(m_procInfoWidget, &ProcInfoWidget::sendSpeed, this, [this](unsigned long upload, unsigned long download){
        if (!m_tipLabel->isVisible()) {
            return;
        }

        const QString speedLabelText = QString("↑%1/s\n↓%2/s")
                .arg(formatBytesByDefault(upload))
                .arg(formatBytesByDefault(download));
        m_tipLabel->setText(speedLabelText);
        m_tipLabel->adjustSize();
    });

    qDebug() << "ProcInfoPlugin ===init==================================================";
}

QWidget *ProcInfoPlugin::itemWidget(const QString &itemKey)
{
    Q_UNUSED(itemKey);

    // 这里暂时返回空指针，这意味着插件会被 dde-dock 加载
    // 但是不会有任何东西被添加到 dde-dock 上
    return m_procInfoWidget;
}

QWidget *ProcInfoPlugin::itemTipsWidget(const QString &itemKey)
{
    Q_UNUSED(itemKey);
    return m_tipLabel;
}

bool ProcInfoPlugin::pluginIsAllowDisable()
{
    // 告诉 dde-dock 本插件允许禁用
    return true;
}

bool ProcInfoPlugin::pluginIsDisable()
{
    // 第二个参数 “disabled” 表示存储这个值的键（所有配置都是以键值对的方式存储的）
    // 第三个参数表示默认值，即默认不禁用
    return m_proxyInter->getValue(this, "disabled", false).toBool();
}

void ProcInfoPlugin::pluginStateSwitched()
{
    // 获取当前禁用状态的反值作为新的状态值
    const bool disabledNew = !pluginIsDisable();
    // 存储新的状态值
    m_proxyInter->saveValue(this, "disabled", disabledNew);

    // 根据新的禁用状态值处理主控件的加载和卸载
    if (disabledNew) {
        m_proxyInter->itemRemoved(this, pluginName());
    } else {
        m_proxyInter->itemAdded(this, pluginName());
    }
}

int ProcInfoPlugin::itemSortKey(const QString &itemKey)
{
    Q_UNUSED(itemKey);

    const QString key = QString("pos_%1").arg(Dock::Efficient);
    return m_proxyInter->getValue(this, key, 0).toInt();
}

void ProcInfoPlugin::setSortKey(const QString &itemKey, const int order)
{
    Q_UNUSED(itemKey);

    const QString key = QString("pos_%1").arg(Dock::Efficient);
    m_proxyInter->saveValue(this, key, order);
}

const QString ProcInfoPlugin::itemCommand(const QString &itemKey)
{
    Q_UNUSED(itemKey);
    const QString &cmd = "bash /opt/apps/com.github.ccc-proc-info-plugin/files/Scripts/LancherProcInfoWindowByDaemon.sh";
    return cmd;
}

const QString ProcInfoPlugin::itemContextMenu(const QString &itemKey)
{
    Q_UNUSED(itemKey);

    QList<QVariant> items;
    items.reserve(3);

    // QMap<QString, QVariant> refresh;
    // refresh["itemId"] = "refresh";
    // refresh["itemText"] = "刷新";
    // refresh["isActive"] = true;
    // items.push_back(refresh);

    QMap<QString, QVariant> open;
    open["itemId"] = "open";
    open["itemText"] = "打开系统监视器";
    open["isActive"] = true;
    items.push_back(open);

    QMap<QString, QVariant> setting;
    setting["itemId"] = "setting";
    setting["itemText"] = "设置";
    setting["isActive"] = true;
    items.push_back(setting);

    QMap<QString, QVariant> about;
    about["itemId"] = "about";
    about["itemText"] = "关于";
    about["isActive"] = true;
    items.push_back(about);

    QMap<QString, QVariant> menu;
    menu["items"] = items;
    menu["checkableMenu"] = false;
    menu["singleCheck"] = false;

    // 返回 JSON 格式的菜单数据
    return QJsonDocument::fromVariant(menu).toJson();

    // return PluginsItemInterface::itemContextMenu(itemKey);
}

void ProcInfoPlugin::invokedMenuItem(const QString &itemKey, const QString &menuId, const bool checked)
{
    Q_UNUSED(itemKey);
    Q_UNUSED(checked);

    // 根据上面接口设置的 id 执行不同的操作
    if (menuId == "refresh") {
        m_proxyInter->itemRemoved(this, pluginName());
        m_proxyInter->itemAdded(this, pluginName());
    } else if (menuId == "open") {
        QDBusInterface ifc("org.desktopspec.ApplicationManager1",
                           "/org/desktopspec/ApplicationManager1/deepin_2dsystem_2dmonitor",
                           "org.desktopspec.ApplicationManager1.Application");
        if (ifc.isValid())
            ifc.call("Launch", "", QStringList(), QVariantMap());
        else
            m_model->AsyncExecProgram("/usr/bin/deepin-system-monitor", {});
    } else if (menuId == "setting") {
        m_model->AsyncExecProgram("/opt/apps/com.github.ccc-proc-info-plugin/files/Tools/CccProcInfoWindow",
                                QStringList{QString("--%1").arg(EXEC_PARAMS_CFG_KEY_OPEN_SETTINGS_PAGE)});
    } else if (menuId == "about") {
        m_model->AsyncExecProgram("/opt/apps/com.github.ccc-proc-info-plugin/files/Tools/CccProcInfoWindow",
                                QStringList{QString("--%1").arg(EXEC_PARAMS_CFG_KEY_OPEN_ABOUT_DLG)});
    }
}

void ProcInfoPlugin::displayModeChanged(const Dock::DisplayMode displayMode)
{
    Q_UNUSED(displayMode);
    //    dismode=displayMode;
}
void ProcInfoPlugin::positionChanged(const Dock::Position position)
{
    Q_UNUSED(position);
    //    pos=position;
}

void ProcInfoPlugin::pluginSettingsChanged()
{
    qDebug() << "pluginSettingsChanged";
    m_proxyInter->itemRemoved(this, pluginName());
    m_proxyInter->itemAdded(this, pluginName());
}

PluginsItemInterface::PluginSizePolicy ProcInfoPlugin::pluginSizePolicy() const
{
    return PluginSizePolicy::Custom;
}
